/*
 * ksAtomBlockReader.cpp
 *
 *  Created on: Aug 3, 2011
 *      Author: wang
 */

#include "ksAtomBlockReader.h"
#include <cstring>
#include <fstream>
#include <sstream>

#include "../ksDefines.h"
#include "../ksData.h"

ksAtomBlockReader::ksAtomBlockReader()
        : _data(NULL)
{

}

ksAtomBlockReader::~ksAtomBlockReader()
{
    delete[] _data;
}

void ksAtomBlockReader::loadHeader(unsigned char* data, unsigned int length)
{
    int copySize = sizeof(_atomBlockHeader);
    memcpy(&_blockHeader.atom, data, copySize);

    description();
}
void ksAtomBlockReader::load(std::ifstream & input)
{
    LogObj("");
    size_t at = input.tellg();

    // load header
    unsigned char headerBuffer[kAtomBlockHeaderLength] = { 0 };
    input.read((char*) headerBuffer, kAtomBlockHeaderLength);
    loadHeader(headerBuffer, kAtomBlockHeaderLength);
    size_t hend = input.tellg();

    // read the data
    _data = new unsigned char[_align4(_blockHeader.atom.dataLength)];
    input.read((char*) _data, _align4(_blockHeader.atom.dataLength));
    std::cout << "ksAtomBlockReader::load at:" << at;
    std::cout << " header end:" << hend;
    std::cout << " end:" << input.tellg() << std::endl;
}

void ksAtomBlockReader::extract(const char *path)
{
    std::stringstream stringStream;
    stringStream << _blockHeader.atom.id;
    std::string filename = stringStream.str();

    std::string fullpath = std::string(path) + filename;
    std::ofstream output;
    output.open(fullpath.c_str(), std::ofstream::out | std::ofstream::binary);
    if (output.good())
    {
        DATA content = { (char*) _data, _blockHeader.atom.dataLength };
        DATA* pData = &content;
        if (_blockHeader.atom.encrypt)
        {
            DATA decryptData = decrypt(*pData);
            freeData(*pData);
            pData = &decryptData;
            if (!pData->ptr || !pData->length)
            {
                std::cout << "decrypt failed" << std::endl;
                description();
            }
        }

        if (_blockHeader.atom.compress)
        {
            DATA decompressData = decompress(*pData);
            freeData(*pData);
            pData = &decompressData;

            if (!pData->ptr || !pData->length)
            {
                std::cout << "decompress failed" << std::endl;
                description();
            }
        }
        output.write((char*) pData->ptr, pData->length);

        freeData(*pData);
    }
    else
    {
        std::cout << "write file filed:" << fullpath << std::endl;
    }

    output.close();
}

